<template>
  <div style="height: calc(100vh - 175px)">
    <div class="time">
      <!-- <div class="time-left">
        <el-radio-group v-model="timeRadio">
          <el-radio-button label="全部" :value="0" />
          <el-radio-button label="7天" :value="7" />
          <el-radio-button label="自定义" :value="0" />
        </el-radio-group>
        <el-date-picker v-model="date" type="datetimerange" start-placeholder="开始时间" end-placeholder="结束时间"
          :default-time="defaultTime" v-if="timeRadio == 3" />
      </div> -->
      <div class="time-right">
        <el-button @click="handleRefresh" :icon="Refresh" />
        <el-button @click="handleCardSet" :icon="Setting">卡片设置</el-button>
      </div>
    </div>
    <div style="height: calc(100% - 30px);overflow:hidden auto;">
      <el-row :gutter="20" class="statistics" :key="forceUpdate">
        <el-col v-for="(item, index) of list" :key="index" :xl="item.size" :lg="item.size" :md="item.size"
          :sm="item.size" :xs="item.size">
          <el-card shadow="never" v-if="item.title == '项目概览'">
            <template #header>
              <div class="card-header" style="display: flex;align-items: center;justify-content: space-between">
                <span>项目概览</span>
                <div class="time-left">
                  <el-radio-group v-model="timeRadio" @change="changeTime">
                    <el-radio-button label="全部" :value="1" />
                    <el-radio-button label="7天" :value="7" />
                    <el-radio-button label="自定义" :value="3" />
                  </el-radio-group>
                  <el-date-picker v-model="date" type="datetimerange" start-placeholder="开始时间" end-placeholder="结束时间"
                    :default-time="defaultTime" v-if="timeRadio == 3" @change="changeTime" format="YYYY-MM-DD HH:mm:ss"
                    value-format="YYYY-MM-DD HH:mm:ss" />
                </div>
              </div>
            </template>
            <el-row :gutter="20" class="view">
              <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
                <span class="view-img">
                  <img src="@/assets/svgs/api.svg" alt="" srcset="" />
                </span>
                <div class="view-content">
                  <div class="view-content_title">接口API</div>
                  <CountTo class="text-20px view-content_value" :start-val="0" :end-val="viewData.apiCount"
                    :duration="2600" />
                </div>
              </el-col>
              <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
                <span class="view-img">
                  <img src="@/assets/svgs/caseWhite.svg" alt="" srcset="" />
                </span>
                <div class="view-content">
                  <div class="view-content_title">接口用例</div>
                  <CountTo class="text-20px view-content_value" :start-val="0" :end-val="viewData.apiCaseCount"
                    :duration="2600" />
                </div>
              </el-col>
              <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
                <span class="view-img">
                  <img src="@/assets/svgs/scence.svg" alt="" srcset="" />
                </span>
                <div class="view-content">
                  <div class="view-content_title">接口场景</div>
                  <CountTo class="text-20px view-content_value" :start-val="0" :end-val="viewData.apiSceneCount"
                    :duration="2600" />
                </div>
              </el-col>
            </el-row>
          </el-card>
          <el-card shadow="never" v-else-if="item.title == '接口数'">
            <template #header>
              <div class="card-header">
                <span>接口数</span>
              </div>
            </template>
            <el-row :gutter="20">
              <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12">
                <el-row class="count">
                  <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12">
                    <div class="count-title">接口数</div>
                    <div class="count-num">{{ coverData.allApiCount }}</div>
                  </el-col>
                  <!-- <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12">
                    <div class="count-title">未覆盖</div>
                    <div class="count-num">{{ coverData.coverWithApiDefinition }}</div>
                  </el-col> -->
                </el-row>
              </el-col>
              <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12">
                <el-row class="count">
                  <template v-for="(item, index) of apiCountCompletionRate" :key="index">
                    <el-col :xl="6" :lg="6" :md="6" :sm="6" :xs="6" v-if="item.name != '完成率'">
                      <div class="count-title">{{ item.name }}</div>
                      <div class="count-num">{{ item.count }}</div>
                    </el-col>
                  </template>
                </el-row>
              </el-col>
            </el-row>
            <el-row style="margin-top: 10px">
              <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12" style="position: relative;">
                <el-tooltip content="接口下存在用例或在场景步骤导入的接口/接口总数*100%" placement="top">
                  <span class="rate">{{ apiCoverRatio }}</span>
                </el-tooltip>
                <Echart :options="pieCoverData" :height="150" ref="interfaceCountRef" />
              </el-col>
              <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12" style="position: relative;">
                <el-tooltip content="接口状态为已完成的接口数/接口总数*100%" placement="top">
                  <span class="rate">{{ apiCompleteRatio }}</span>
                </el-tooltip>
                <Echart :options="pieCompleteData" :height="150" ref="interfaceCountRef" />
              </el-col>
            </el-row>
          </el-card>
          <el-card shadow="never" v-else-if="item.title == '接口用例数'">
            <template #header>
              <div class="card-header">
                <span>接口用例数</span>
              </div>
            </template>
            <el-row :gutter="20">
              <template v-for="(item, index) of caseApiCount" :key="index">
                <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12">
                  <el-row class="count">
                    <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12">
                      <div class="count-title">{{ item.name }}</div>
                      <div class="count-num">{{ item.count }}</div>
                    </el-col>
                  </el-row>
                </el-col>
              </template>
              <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12">
                <el-row class="count">
                  <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12" v-for="(item, index) of casePassCount"
                    :key="index">
                    <div class="count-title">{{ item.name }}</div>
                    <div class="count-num">{{ item.value }}</div>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
            <el-row style="margin-top: 10px">
              <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8" style="position: relative;">
                <el-tooltip content="存在接口用例的接口数/接口总数*100%" placement="top">
                  <span class="rate">{{ caseCoverRatio }}</span>
                </el-tooltip>
                <Echart :options="pieCoverRatio" :height="150" ref="interfaceCountRef" />
              </el-col>
              <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8" style="position: relative;">
                <el-tooltip content="执行过的接口用例/总接口用例数*100%" placement="top">
                  <span class="rate">{{ caseExecuteRatio }}</span>
                </el-tooltip>
                <Echart :options="pieCaseExecuteRatio" :height="150" ref="interfaceCountRef" />
              </el-col>
              <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8" style="position: relative;">
                <el-tooltip content="最后一次执行成功的用例/总接口用例数*100%" placement="top">
                  <span class="rate">{{ casePassRatio }}</span>
                </el-tooltip>
                <Echart :options="pieCaseExcessRatio" :height="150" ref="interfaceCountRef" />
              </el-col>
            </el-row>
          </el-card>
          <el-card shadow="never" v-else-if="item.title == '场景用例数' || item.title == '场景数'">
            <template #header>
              <div class="card-header">
                <span>场景数</span>
              </div>
            </template>
            <el-row :gutter="20">
              <template v-for="(item, index) of sceneApiCount" :key="index">
                <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12">
                  <el-row class="count">
                    <el-col :xl="12" :lg="12" :md="12" :sm="12" :xs="12">
                      <div class="count-title">{{ item.name }}</div>
                      <div class="count-num">{{ item.count }}</div>
                    </el-col>
                  </el-row>
                </el-col>
              </template>
            </el-row>
            <el-row style="margin-top: 10px">
              <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8" style="position: relative;">
                <el-tooltip content="场景步骤中导入的接口数（或导入该接口中的接口用例）/接口总数*100%" placement="top">
                  <span class="rate">{{ sceneCoverRatio }}</span>
                </el-tooltip>
                <Echart :options="pieSceneCover" :height="150" ref="interfaceCountRef" />
              </el-col>
              <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8" style="position: relative;">
                <el-tooltip content="执行过的场景数/场景总数*100%" placement="top">
                  <span class="rate">{{ sceneExecuteRatio }}</span>
                </el-tooltip>
                <Echart :options="pieSceneExecute" :height="150" ref="interfaceCountRef" />
              </el-col>
              <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8" style="position: relative;">
                <el-tooltip content="最后一次执行成功的场景数/场景总数*100%" placement="top">
                  <span class="rate">{{ scenePassRatio }}</span>
                </el-tooltip>
                <Echart :options="pieSceneExcess" :height="150" ref="interfaceCountRef" />
              </el-col>
            </el-row>
          </el-card>
        </el-col>
      </el-row>
    </div>
    <cardSetting ref="cardSetRef" />
  </div>
</template>

<script setup lang="ts">
import { set } from 'lodash-es'
import { useAppStore } from '@/store/modules/app'
import { pieOptions1, pieOptions2 } from './echarts-data'
import cardSetting from './cardSetting.vue';
import { useDebugStore } from '@/store/modules/debug'
import { Setting, Refresh } from '@element-plus/icons-vue'
import * as DebugApi from '@/api/debug'
const appStore = useAppStore()
let projectId = computed(() => appStore.getSelectProject)
const debugStore = useDebugStore()
const list = computed(() => debugStore.getList)
const timeRadio = ref(1)
const date = ref('')
const defaultTime = ref()
const interfaceCountRef = ref()
const pieCoverData = reactive(pieOptions1()) as any
const pieCompleteData = reactive(pieOptions2()) as any
const pieCoverRatio = reactive(pieOptions1()) as any
const pieCaseExecuteRatio = reactive(pieOptions1()) as any
const pieCaseExcessRatio = reactive(pieOptions1()) as any
const pieSceneCover = reactive(pieOptions1()) as any
const pieSceneExecute = reactive(pieOptions1()) as any
const pieSceneExcess = reactive(pieOptions1()) as any
const cardSetRef = ref()
const forceUpdate = ref(0)
const viewData = ref({} as any)
const coverData = ref({} as any)
const apiCountCompletionRate = ref([] as any)
const sceneApiCount = ref([] as any)
const caseApiCount = ref([] as any)
const casePassCount = ref([] as any)
const scenePassRatio = ref('')
const sceneExecuteRatio = ref('')
const sceneCoverRatio = ref('')
const caseCoverRatio = ref('')
const caseExecuteRatio = ref('')
const casePassRatio = ref('')
const apiCoverRatio = ref('')
const apiCompleteRatio = ref('')
watch(() => list.value, () => {
  forceUpdate.value++
}, {
  deep: true
})
watch(() => projectId.value, async () => {
  handleRefresh()
})
const init = () => {
  const textColor = appStore.getIsDark ? '#fff' : 'rgb(48, 49, 51)'
  pieCoverData.title.textStyle.color = textColor
  pieCoverData.legend.textStyle.rich.name.color = textColor
  pieCompleteData.title.textStyle.color = textColor
  pieCompleteData.legend.textStyle.rich.name.color = textColor
  pieCoverRatio.title.textStyle.color = textColor
  pieCoverRatio.legend.textStyle.rich.name.color = textColor
  pieCaseExecuteRatio.title.textStyle.color = textColor
  pieCaseExecuteRatio.legend.textStyle.rich.name.color = textColor
  pieCaseExcessRatio.title.textStyle.color = textColor
  pieCaseExcessRatio.legend.textStyle.rich.name.color = textColor
  pieSceneCover.title.textStyle.color = textColor
  pieSceneCover.legend.textStyle.rich.name.color = textColor
  pieSceneExecute.title.textStyle.color = textColor
  pieSceneExecute.legend.textStyle.rich.name.color = textColor
  pieSceneExcess.title.textStyle.color = textColor
  pieSceneExcess.legend.textStyle.rich.name.color = textColor
}
/** 监听主题切换 */
watchEffect(() => {
  init()
})
/** 刷新 */
const handleRefresh = () => {
  getApiView()
  getApiCoverData()
  getApiCount()
  getSceneApiCount()
  getCaseApiCount()
}
/** 时间切换 */
const changeTime = () => {
  if (timeRadio.value == 3 && !date.value) {
    return
  }
  if (timeRadio.value != 3) {
    date.value = ''
  }
  getApiView()
}
/** 卡片设置 */
const handleCardSet = () => {
  cardSetRef.value.open()
}
/** 接口数-覆盖率 */
const getPieCoverData = async (unCover, cover) => {
  const data = [
    { name: '已覆盖', value: cover },
    { name: '未覆盖', value: unCover }
  ]
  set(
    pieCoverData,
    'color',
    ["#30e254", "#eee"]
  )
  set(
    pieCoverData,
    'title.text',
    '接口数覆盖率'
  )
  set(
    pieCoverData,
    'legend.data',
    ['已覆盖', '未覆盖']
  )
  set(
    pieCoverData,
    'series[0].data',
    data
  )
  set(
    pieCoverData,
    'legend.formatter',
    function (name) {
      let res = data.filter((v) => v.name === name);
      return "{name| " + name + "}{value| " + res[0].value + "}";
    }
  )
}
/** 接口数-完成率 */
const getPieCompleteData = async (data, legend) => {
  set(
    pieCompleteData,
    'title.text',
    '接口完成率'
  )
  set(
    pieCompleteData,
    'series[0].data',
    data
  )
  set(
    pieCompleteData,
    'legend.data',
    legend
  )
  set(
    pieCompleteData,
    'legend.formatter',
    function (name) {
      let res = data.filter((v) => v.name === name);
      return "{name| " + name + "}{value| " + res[0].value + "}";
    }
  )
}
/** 接口用例数-覆盖率 */
const getPieCoverRatio = async (unCover, cover) => {
  const data = [
    { name: '已覆盖', value: cover },
    { name: '未覆盖', value: unCover }
  ]
  set(
    pieCoverRatio,
    'color',
    ["#30e254", "#eee"]
  )
  set(
    pieCoverRatio,
    'title.text',
    '接口用例覆盖率'
  )
  set(
    pieCoverRatio,
    'series[0].data',
    data
  )
  set(
    pieCoverRatio,
    'legend.data',
    ['已覆盖', '未覆盖']
  )
  set(
    pieCoverRatio,
    'legend.formatter',
    function (name) {
      let res = data.filter((v) => v.name === name);
      return "{name| " + name + "}{value| " + res[0].value + "}";
    }
  )
}
/** 接口用例数-执行率 */
const getPieCaseExecuteRatio = async (data, legend) => {
  set(
    pieCaseExecuteRatio,
    'color',
    ["#eee", "#30e254"]
  )
  set(
    pieCaseExecuteRatio,
    'title.text',
    '用例执行率'
  )
  set(
    pieCaseExecuteRatio,
    'series[0].data',
    data
  )
  set(
    pieCaseExecuteRatio,
    'legend.data',
    legend
  )
  set(
    pieCaseExecuteRatio,
    'legend.formatter',
    function (name) {
      let res = data.filter((v) => v.name === name);
      return "{name| " + name + "}{value| " + res[0].value + "}";
    }
  )
}
/** 接口用例数-通过率 */
const getPieCaseExcessRatio = async (data, legend) => {
  set(
    pieCaseExcessRatio,
    'color',
    ["#e82b1d", "#30e254"]
  )
  set(
    pieCaseExcessRatio,
    'title.text',
    '用例通过率'
  )
  set(
    pieCaseExcessRatio,
    'series[0].data',
    data
  )
  set(
    pieCaseExcessRatio,
    'legend.data',
    legend
  )
  set(
    pieCaseExcessRatio,
    'legend.formatter',
    function (name) {
      let res = data.filter((v) => v.name === name);
      return "{name| " + name + "}{value| " + res[0].value + "}";
    }
  )
}
/** 场景用例数-覆盖率 */
const getPieSceneCoverRatio = async (unCover, cover) => {
  const data = [
    { name: '已覆盖', value: cover },
    { name: '未覆盖', value: unCover }
  ]
  set(
    pieSceneCover,
    'color',
    ["#30e254", "#eee"]
  )
  set(
    pieSceneCover,
    'title.text',
    '场景接口覆盖率'
  )
  set(
    pieSceneCover,
    'series[0].data',
    data
  )
  set(
    pieSceneCover,
    'legend.data',
    ['已覆盖', '未覆盖']
  )
  set(
    pieSceneCover,
    'legend.formatter',
    function (name) {
      let res = data.filter((v) => v.name === name);
      return "{name| " + name + "}{value| " + res[0].value + "}";
    }
  )
}
/** 场景用例数-执行率 */
const getPieSceneCaseExecuteRatio = async (data, legend) => {
  set(
    pieSceneExecute,
    'color',
    ["#eee", "#30e254"]
  )
  set(
    pieSceneExecute,
    'title.text',
    '场景执行率'
  )
  set(
    pieSceneExecute,
    'series[0].data',
    data
  )
  set(
    pieSceneExecute,
    'legend.data',
    legend
  )
  set(
    pieSceneExecute,
    'legend.formatter',
    function (name) {
      let res = data.filter((v) => v.name === name);
      return "{name| " + name + "}{value| " + res[0].value + "}";
    }
  )
}
/** 场景用例数-通过率 */
const getPieSceneCaseExcessRatio = async (data, legend) => {
  set(
    pieSceneExcess,
    'color',
    ["#e82b1d", "#30e254"]
  )
  set(
    pieSceneExcess,
    'title.text',
    '场景通过率'
  )
  set(
    pieSceneExcess,
    'series[0].data',
    data
  )
  set(
    pieSceneExcess,
    'legend.data',
    legend
  )
  set(
    pieSceneExcess,
    'legend.formatter',
    function (name) {
      let res = data.filter((v) => v.name === name);
      return "{name| " + name + "}{value| " + res[0].value + "}";
    }
  )
}
/** 接口概览 */
const getApiView = async () => {
  let params = { projectId: projectId.value } as any
  if (timeRadio.value == 7) {
    params.dayNumber = 7
  } else if (timeRadio.value == 3) {
    params.createTime = date.value
  }
  let res = await DebugApi.getApiView(params)
  viewData.value = res
}
/** 覆盖率数据 */
const getApiCoverData = async () => {
  let { allApiCount, unCoverWithApiDefinition, coverWithApiDefinition, apiCoverage, unCoverWithApiCase, coverWithApiCase, apiCaseCoverage, unCoverWithApiScenario, coverWithApiScenario, scenarioCoverage } = await DebugApi.getApiCoverage({ projectId: projectId.value })
  coverData.value = { allApiCount, unCoverWithApiDefinition, coverWithApiDefinition }
  apiCoverRatio.value = apiCoverage
  caseCoverRatio.value = apiCaseCoverage
  sceneCoverRatio.value = scenarioCoverage
  getPieCoverData(unCoverWithApiDefinition, coverWithApiDefinition)
  getPieCoverRatio(unCoverWithApiCase, coverWithApiCase)
  getPieSceneCoverRatio(unCoverWithApiScenario, coverWithApiScenario)
}
/** 接口数量统计、完成率 */
const getApiCount = async () => {
  let { completionRate } = await DebugApi.getApiCount({ projectId: projectId.value })
  apiCountCompletionRate.value = completionRate
  const completeRatio = completionRate.find(n => n.name.indexOf('率') != -1).count
  apiCompleteRatio.value = completeRatio
  const echartsData = [] as any, legendData = [] as any
  completionRate.forEach(item => {
    if (item.name.indexOf('率') == -1) {
      echartsData.push({
        name: item.name,
        value: item.count
      })
      legendData.push(item.name)
    }
  })
  getPieCompleteData(echartsData, legendData)
}
/** 场景数量统计、执行率、通过率 */
const getSceneApiCount = async () => {
  let { apiScenarioCount, execCount, execRate, passRate } = await DebugApi.getApiSceneCount({ projectId: projectId.value })
  sceneApiCount.value = [...execCount, ...apiScenarioCount]
  const execRatio = execRate.find(n => n.name.indexOf('率') != -1).count
  const passRatio = passRate.find(n => n.name.indexOf('率') != -1).count
  scenePassRatio.value = passRatio
  sceneExecuteRatio.value = execRatio
  let echartsData = [] as any, legendData = [] as any, passEchartsData = [] as any, passLegendData = [] as any
  execRate.forEach(item => {
    if (item.name.indexOf('率') == -1) {
      echartsData.push({
        name: item.name,
        value: item.count
      })
      legendData.push(item.name)
    }
  })
  passRate.forEach(item => {
    if (item.name.indexOf('率') == -1) {
      passEchartsData.push({
        name: item.name,
        value: item.count
      })
      passLegendData.push(item.name)
    }
  })
  getPieSceneCaseExecuteRatio(echartsData, legendData)
  getPieSceneCaseExcessRatio(passEchartsData, passLegendData)
}
/** 接口用例数量统计、执行率、通过率 */
const getCaseApiCount = async () => {
  let { apiCaseCount, execRate, passRate } = await DebugApi.getApiCaseCount({ projectId: projectId.value })
  caseApiCount.value = [...apiCaseCount]
  const execRatio = execRate.find(n => n.name.indexOf('率') != -1).count
  const passRatio = passRate.find(n => n.name.indexOf('率') != -1).count
  casePassRatio.value = passRatio
  caseExecuteRatio.value = execRatio
  let echartsData = [] as any, legendData = [] as any, passEchartsData = [] as any, passLegendData = [] as any
  execRate.forEach(item => {
    if (item.name.indexOf('率') == -1) {
      echartsData.push({
        name: item.name,
        value: item.count
      })
      legendData.push(item.name)
    }
  })
  passRate.forEach(item => {
    if (item.name.indexOf('率') == -1) {
      passEchartsData.push({
        name: item.name,
        value: item.count
      })
      passLegendData.push(item.name)
    }
  })
  casePassCount.value = passEchartsData
  getPieCaseExecuteRatio(echartsData, legendData)
  getPieCaseExcessRatio(passEchartsData, passLegendData)
}
onMounted(() => {
  if (projectId.value) {
    getApiView()
    getApiCoverData()
    getApiCount()
    getSceneApiCount()
    getCaseApiCount()
  }
})
</script>

<style scoped lang="scss">
.rate {
  position: absolute;
  left: 50%;
  top: 32%;
  transform: translateX(-50%);
  z-index: 10;
  font-weight: bold;
}

.statistics {

  .el-col {
    margin-bottom: 20px;
  }
}

.time {
  margin-bottom: 20px;
  display: flex;
  justify-content: space-between;

  &-left {
    display: flex;
    align-items: center;

    :deep(.el-date-editor) {
      margin-left: 10px;
    }
  }
}

.view {
  display: flex;
  justify-content: space-between;
  padding: 0 10px;

  .el-col {
    display: flex;
    align-items: baseline;
    padding: 10px;
    box-sizing: border-box;
    max-width: 32.5%;

    .view-img {
      width: 25px;
      height: 25px;
      border-radius: 100%;
      background: #3370ff;
      color: #fff;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
      top: 5px;

      img {
        width: 18px;
      }
    }

    .view-content {
      margin-left: 10px;
      font-size: 14px;

      &_title {}

      &_value {}
    }
  }
}

.count {
  align-items: center;
  padding: 10px;
  height: 90px;

  &-title {
    margin-bottom: 10px;
    font-size: 14px;
  }

  &-num {
    color: #9441b1;
    font-size: 18px;
  }
}

.count-b {
  align-items: center;
}

.light {
  .count {
    background: #f9f9fe;

    &-title {
      color: #959598;
    }
  }

  .view {
    .el-col {
      border: 1px solid #e9e8e8;
    }
  }
}

.dark {
  .count {
    background: #56565733;

    &-title {
      color: #fff;
    }
  }

  .view {
    .el-col {
      border: 1px solid #494848;
    }
  }
}
</style>
